﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;

using AvalonDock;
using iStudio.Format;
using iStudio.Library;
using iStudio.Structure.Command;
using iStudio.Structure.Engine;
using iStudio.Structure.Message;
using iStudio.View.Dialog;

namespace iStudio.View
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        public MainWindow ()
        {
            InitializeComponent ();

            //
            // Register UiClient to receive messages
            //

            MessageServer.Instance.Subscribe (new UiClient ());

            //
            // Setup audio elements
            //

            AudioEngine soundEngine = AudioEngine.Instance;
            soundEngine.PropertyChanged += AudioEnginePropertyChanged;

            trackEditor.RegisterSoundPlayer (soundEngine);

            //
            // Setup default track editor renderer and tool from modules
            //

            if (Manager.Manager.Instance.PluginManager.EditorRenderers.Count > 0)
            {
                trackEditor.SetupRenderer (Manager.Manager.Instance.PluginManager.EditorRenderers[0]);
            }

            if (Manager.Manager.Instance.PluginManager.EditorTools.Count > 0)
            {
                trackEditor.SetupTool (Manager.Manager.Instance.PluginManager.EditorTools[0]);
            }

            //
            // Leave analyzer static for now
            //

            mainAnalyzer.RegisterSoundPlayer (soundEngine);

            InitializeMenuHooks ();
        }

        public void OpenDockableWindow (DockableContent dockedWindow)
        {
            pane_module.Items.Add (dockedWindow);

            //dockedWindow.ShowAsFloatingWindow (dockManager, true);

            dockedWindow.Activate ();
        }

        private void InitializeMenuHooks ()
        {
            //
            // Add all commands
            //

            MenuInitializer.InitializeMenu (menu_main, Manager.Manager.Instance.PluginManager.Modules);
        }

        private void AudioEnginePropertyChanged (object sender, PropertyChangedEventArgs e)
        {
            AudioEngine engine = AudioEngine.Instance;

            switch (e.PropertyName)
            {
                case "ChannelPosition":
                    mainClock.Time = TimeSpan.FromSeconds (engine.ChannelPosition);

                    break;
            }
        }

        private void BorderMouseDown (object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                DragMove ();
            }
        }

        private void DockManagerLoaded (object sender, RoutedEventArgs e)
        {
            //
            // Initial setup of the layout
            //

            pane_bottom.ToggleAutoHide ();
        }

        private void WindowClosing (object sender, CancelEventArgs e)
        {
            AudioEngine.Instance.Stop ();
            AudioEngine.Instance.Dispose ();
        }

        private void MenuOpenClick (object sender, RoutedEventArgs e)
        {
            throw new NotImplementedException ("Open project functionality is not yet implemented.");
        }

        private void MenuImportFileClick (object sender, RoutedEventArgs e)
        {
            //
            // Create filter
            //

            List<FormatDescriptor> supportedFormats = Manager.Manager.Instance.PluginManager.GetSupportedFileFormats (FormatSupport.CanOpen);

            if (supportedFormats.Count > 0)
            {

                Microsoft.Win32.OpenFileDialog open = new Microsoft.Win32.OpenFileDialog
                                                          {
                                                              Filter = Format.Format.CreateFilterString (supportedFormats),
                                                              Title = "Import sound files",
                                                              Multiselect = true
                                                          };

                if (open.ShowDialog () == true)
                {
                    //
                    // Go through all files
                    //

                    foreach (string file in open.FileNames)
                    {
                        foreach (Format.Format format in Manager.Manager.Instance.PluginManager.Formats)
                        {
                            try
                            {
                                AudioEngine.Instance.Project.AddTrack (format.Import (file));

                                ConsoleLog ("Opened file: " + file);

                                // Stop importing file if it was successful
                                break;
                            }
                            // ReSharper disable EmptyGeneralCatchClause
                            catch (System.Exception ex)
                            // ReSharper restore EmptyGeneralCatchClause
                            {
                                ConsoleLog ("Cannot open file: " + file + " using library: " + format.Name + " Error: " + ex.Message);
                            }
                        }
                    }
                }
            }
            else
            {
                LockUi ();

                Alert.Show (this, "Could not locate any format plugins. Check if your iStudio installation is complete and verify if all format files (starting with iStudio.Format.* usually) are in application directory.\n\nIf you believe all files you need are there, try to replace the files with new ones, because they might be corrupt.");

                UnlockUi ();
            }
        }

        private void LockUi ()
        {
            overlayGrid.Visibility = Visibility.Visible;
        }

        private void UnlockUi ()
        {
            overlayGrid.Visibility = Visibility.Hidden;
        }

        private void MenuAboutClick (object sender, RoutedEventArgs e)
        {
            LockUi ();   

            About aboutDialog = new About
                                    {
                                        Owner = this
                                    };

            aboutDialog.ShowDialog ();

            UnlockUi ();
        }

        private void MenuExitClick (object sender, RoutedEventArgs e)
        {
            AudioEngine.Instance.Stop ();
            AudioEngine.Instance.Dispose ();

            Application.Current.Shutdown ();
        }

        private void MenuConsoleClick (object sender, RoutedEventArgs e)
        {
            if (dock_console.IsVisible == false)
            {
                dock_console.Show ();
            }
            else
            {
                dock_console.Activate ();
            }
        }

        private void MenuSaveClick (object sender, RoutedEventArgs e)
        {
            throw new NotImplementedException("Save project functionality is not yet implemented.");
        }

        public void ConsoleLog (string log)
        {
            string dateString = DateTime.Now.ToString ("[HH:mm:ss]");

            console.Dispatcher.BeginInvoke (new Action (delegate
                                                            {
                                                                console.Text += dateString + " " + log + "\n";

                                                                console.CaretIndex = console.Text.Length - 1;

                                                                console.ScrollToEnd ();

                                                                dock_console.Activate ();
                                                            }));
        }

        private void MenuPreferencesClick(object sender, RoutedEventArgs e)
        {
            LockUi ();

            Preferences preferenceDialog = new Preferences
                                               {
                                                   Owner = this
                                               };

            preferenceDialog.ShowDialog();

            UnlockUi ();
        }

        private void MenuExportProjectClick (object sender, RoutedEventArgs e)
        {
            List<FormatDescriptor> supportedFormats = Manager.Manager.Instance.PluginManager.GetSupportedFileFormats(FormatSupport.CanSave); 

            Microsoft.Win32.SaveFileDialog save = new Microsoft.Win32.SaveFileDialog
            {
                Filter = Format.Format.CreateFilterString (supportedFormats, false),
                Title = "Export project"
            };

            if (save.ShowDialog() == true)
            {
                foreach (Format.Format format in Manager.Manager.Instance.PluginManager.Formats)
                {
                    try
                    {
                        format.Export (save.FileName, Format.Format.GetFormatType (save.FileName), AudioEngine.Instance.Project);

                        ConsoleLog("Exported project to file: " + save.FileName);

                        break;
                    }
                    // ReSharper disable EmptyGeneralCatchClause
                    catch (System.Exception)
                    // ReSharper restore EmptyGeneralCatchClause
                    {
                    }
                }
            }
        }
    }
}